package com.kl.modular.sysman.system.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.kl.modular.sysman.system.service.api.ISystemAreaCacheService;
import com.kl.modular.system.dao.model.SystemArea;
import com.kl.modular.system.service.api.ISystemAreaService;
import com.kl.service.ehcache.EhcacheServiceImpl;
import org.apache.commons.beanutils.BeanPredicate;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Predicate;
import org.apache.commons.collections.PredicateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.apache.commons.collections.functors.EqualPredicate;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * 缓存行政区域
 *
 * @author xr_zjb
 * @date 2017/09/08 15:48
 *
 */
@Service
public class SystemAreaCacheServiceImpl implements ISystemAreaCacheService{

    public final static String cacheName = "sysarea_cache";
    public final static String allDataKey = "allDataKey";

    @Autowired
    private ISystemAreaService systemAreaService;

    @Autowired
    private EhcacheServiceImpl ehcacheService;

    /**
     * 查找缓存行政区域数据
     * @param parentId 父级ID
     * @return
     */
    public List<SystemArea> findChildList(Long parentId) {
        List<SystemArea> systemAreaList = ehcacheService.queryCache(SystemAreaCacheServiceImpl.cacheName,
                SystemAreaCacheServiceImpl.allDataKey, List.class);
        if(systemAreaList == null){
            SystemArea systemArea = new SystemArea();
            systemAreaList = systemAreaService.selectListByEntity(systemArea);
            ehcacheService.putCache(SystemAreaCacheServiceImpl.cacheName,
                    SystemAreaCacheServiceImpl.allDataKey,
                    systemAreaList);
        }
        if(parentId == null){
            return systemAreaList;
        }
        EqualPredicate parameter = new EqualPredicate(parentId);
        BeanPredicate tableCoulmn_paramerter = new BeanPredicate("parentid", parameter);
        Predicate[] allPredicateArray = {tableCoulmn_paramerter };
        Predicate allPredicate = PredicateUtils.allPredicate(allPredicateArray);
        Collection<SystemArea> filteredCollection = CollectionUtils.select(systemAreaList, allPredicate);
        return (List)filteredCollection;
    }

    /**
     * 查询行政区域
     * @param id 行政区域ID
     * @return
     */
    public SystemArea findAreaById(Long id) {
        SystemArea area = getFullName(id);
        return area;
    }

    /**
     * 查找父级区域下所有区域的子集
     * @param parentId 父ID
     * @return
     */
    @Override
    public List<SystemArea> findChildAllList(Long parentId) {
        if(parentId == null){
            // 全球数据
            parentId = 1L;
        }
        List<SystemArea> systemAreaList = ehcacheService.queryCache(SystemAreaCacheServiceImpl.cacheName,
                parentId, List.class);
        if(systemAreaList != null){
            return systemAreaList;
        }
        SystemArea partentArea = systemAreaService.selectById(parentId);
        if(partentArea == null){
            return null;
        }
        String likestr = null;
        if(partentArea.getLevel().intValue() == 0){
            likestr = "tr_" + partentArea.getId() + "%";
        }else{
            likestr = partentArea.getPosition() + " tr_"+partentArea.getId();
        }
        EntityWrapper<SystemArea> ew = new EntityWrapper<SystemArea>();
        ew.like("position", likestr);
        ew.and("level!={0}", 4);
        ew.or("id={0}", parentId);
        if(partentArea.getLevel().longValue() == 1L){
            ew.or("position={0}","tr_0");
        }
        systemAreaList = systemAreaService.selectList(ew);
        ehcacheService.putCache(SystemAreaCacheServiceImpl.cacheName,
                parentId,
                systemAreaList);
        return systemAreaList;
    }

    /**
     * 获取完整的区域名称
     * @param id
     * @return
     */
    public SystemArea getFullName(Long id){
        List<SystemArea> systemAreaList = ehcacheService.queryCache(SystemAreaCacheServiceImpl.cacheName,
                SystemAreaCacheServiceImpl.allDataKey, List.class);
        if(systemAreaList == null){
            SystemArea systemArea = new SystemArea();
            systemAreaList = systemAreaService.selectListByEntity(systemArea);
            ehcacheService.putCache(SystemAreaCacheServiceImpl.cacheName,
                    SystemAreaCacheServiceImpl.allDataKey,
                    systemAreaList);
        }
        if(id == null){
            return null;
        }
        int i = 1;
        int xun = 0;
        String propertyName = "id";
        StringBuffer fullName = new StringBuffer();
        SystemArea systemArea = null;
        while(i > 0){
            xun++;
            EqualPredicate parameter = new EqualPredicate(id);
            BeanPredicate tableCoulmn_paramerter = new BeanPredicate(propertyName, parameter);
            Predicate[] allPredicateArray = {tableCoulmn_paramerter };
            Predicate allPredicate = PredicateUtils.allPredicate(allPredicateArray);
            Collection<SystemArea> filteredCollection = CollectionUtils.select(systemAreaList, allPredicate);
            List<SystemArea> areaList = (List)filteredCollection;
            if(areaList == null || areaList.size() == 0){
                break;
            }
            SystemArea systemAreaWhile = areaList.get(0);
            fullName.insert(0,systemAreaWhile.getAreaname());
            propertyName = "id";
            id = systemAreaWhile.getParentid();
            if(xun == 1){
                systemArea = systemAreaWhile;
            }
            i++;
            if(i > 8){
                break;
            }
        }
        systemArea.setFullAreaName(fullName.toString());
        return systemArea;
    }

    /**
     * 刷新缓存的行政区域
     * @param
     * @return
     */
    public void refreshAreaCache(){
        SystemArea systemArea = new SystemArea();
        List<SystemArea> systemAreaList = systemAreaService.selectListByEntity(systemArea);
        ehcacheService.delCache(SystemAreaCacheServiceImpl.cacheName,
                SystemAreaCacheServiceImpl.allDataKey);
        ehcacheService.putCache(SystemAreaCacheServiceImpl.cacheName,
                SystemAreaCacheServiceImpl.allDataKey,
                systemAreaList);
    }
}
